import {getTvaPart, htFromTtc, round, strToFloat} from "../../math";

/** Reacts to edits of ExpensModel fields by recomputing other fields
 *
 * Notifies the caller which fields actually changed and needs to be re-displayed in UI.
 */
const AbstractFieldsLinker = {
    reactMap: null,  // Inheritor must implement
    /** Recomputes other fields according to the field that has just been changed
     *
     * @param fieldName String
     * @param model ExpenseModel
     * @return String[] name of the fields having been recomputed
     */
    reactToFieldChange(fieldName, model) {
        if (Object.hasOwn(this.reactMap, fieldName)) {
            // First recompute (on model)
            for (const rule of this.reactMap[fieldName]) {
                const field = rule[0];
                const f = rule[1];
                let v = f(model);
                if (isNaN(v)) { // Avoid "NaN" in model data…
                    v = null;
                }
                if (v) { // Will skip undefined/null
                    v = round(v);
                }
                model.set(field, v);
            }
            return this.reactMap[fieldName].map(x => x[0]);
        } else {
            return [];
        }
    }
}
/** Describes how to recompute linked fields in HT filling mode
 *
 * HT filling mode = user fills HT + TVA or HT + TVA-rate
 *
 */
export const HtModelFieldsLinker = {
    /*
     * The field to watch
     * value : couples of field to set and the function to set it
     */
    reactMap: {
        tva: [
            ["tva_rate", m => null],
            ["ttc_readonly", m => m.total()],
        ],
        tva_rate: [
            ["tva", m => getTvaPart(strToFloat(m.get('ht')), strToFloat(m.get('tva_rate')))],
            ["ttc_readonly", m => m.total()],
        ],
        ht: [
            ["tva_rate", m => null],
            ["ttc_readonly", m => m.total()],
        ],
    },
};
Object.setPrototypeOf(HtModelFieldsLinker, AbstractFieldsLinker);

/** Describes how to recompute linked fields in TTC filling mode
 *
 * TTC filling mode = user fills TTC + TVA or TTC + TVA-rate
 */
export const TTCModelFieldsLinker = {
    /*
     * The field to watch
     * value : couples of field to set and the function to set it
     */
    reactMap: {
        tva: [
            ["tva_rate", m => null],
            ["ht", m => strToFloat(m.get('ttc_readonly')) - strToFloat(m.get('tva'))],
        ],
        tva_rate: [
            ["ht", m => htFromTtc(strToFloat(m.get('ttc_readonly')), strToFloat(m.get('tva_rate')))],
            ["tva", m => strToFloat(m.get('ttc_readonly')) - strToFloat(m.get('ht'))],
        ],
        ttc_readonly: [
            ["ht", m => strToFloat(m.get('ttc_readonly')) - strToFloat(m.get('tva'))],
            ["tva_rate", m => null],
        ],
    },
};
Object.setPrototypeOf(TTCModelFieldsLinker, AbstractFieldsLinker);
